import { http } from "@/utils/http";
import type { ApiResponse } from "../../user";
import { ensureArray, normalisePagination, toNumber } from "@/api/_helpers";

const CATEGORY_ENDPOINT = "/system/product/category";

export interface CategoryListParams {
  page?: number;
  page_size?: number;
  keyword?: string;
  is_visible?: string | number;
  parent_id?: string | number;
}

export interface CategoryListItem {
  id: number;
  name: string;
  slug: string;
  parent_id: number;
  level: number;
  path: string;
  icon_url?: string | null;
  cover_url?: string | null;
  description?: string | null;
  content?: string | null;
  sort: number;
  is_visible: number;
  create_time?: string | null;
  update_time?: string | null;
}

export interface CategoryPagination {
  total: number;
  pageSize: number;
  currentPage: number;
}

export interface CategoryListResult {
  list: CategoryListItem[];
  pagination: CategoryPagination;
}

export interface CategoryDetail extends CategoryListItem {}

export interface CategorySubmitPayload {
  name: string;
  slug: string;
  parent_id?: number | null;
  icon_url?: string;
  cover_url?: string;
  description?: string;
  content?: string;
  sort?: number;
  is_visible?: number | boolean;
}

export interface CategoryTreeNode extends CategoryListItem {
  children?: CategoryTreeNode[];
}

const mapCategory = (item: Record<string, any>): CategoryListItem => ({
  id: toNumber(item.id, 0),
  name: item.name ?? "",
  slug: item.slug ?? "",
  parent_id: toNumber(item.parent_id, 0),
  level: toNumber(item.level, 1),
  path: item.path ?? "",
  icon_url: item.icon_url ?? null,
  cover_url: item.cover_url ?? null,
  description: item.description ?? null,
  content: item.content ?? null,
  sort: toNumber(item.sort, 0),
  is_visible: toNumber(item.is_visible, 0),
  create_time: item.create_time ?? null,
  update_time: item.update_time ?? null
});

const mapTree = (nodes: any[]): CategoryTreeNode[] => {
  return ensureArray(nodes).map(node => ({
    ...mapCategory(node),
    children: Array.isArray(node.children) ? mapTree(node.children) : undefined
  }));
};

const mapSubmitPayload = (
  payload: CategorySubmitPayload
): Record<string, any> => {
  const data: Record<string, any> = {
    name: payload.name,
    slug: payload.slug,
    parent_id:
      payload.parent_id === null || payload.parent_id === undefined
        ? 0
        : payload.parent_id,
    icon_url: payload.icon_url ?? "",
    cover_url: payload.cover_url ?? "",
    description: payload.description ?? "",
    content: payload.content ?? "",
    sort:
      payload.sort !== undefined && payload.sort !== null
        ? Number(payload.sort)
        : 0,
    is_visible:
      payload.is_visible === undefined || payload.is_visible === null
        ? 1
        : Number(payload.is_visible)
          ? 1
          : 0
  };

  return data;
};

const fetchList = async (
  params: CategoryListParams = {}
): Promise<CategoryListResult> => {
  const page = toNumber(params.page, 1) || 1;
  const pageSize = toNumber(params.page_size, 10) || 10;

  const res = await http.request<ApiResponse<any>>("get", CATEGORY_ENDPOINT, {
    params: {
      ...params,
      page,
      page_size: pageSize
    }
  });

  const payload = (res?.data ?? {}) as Record<string, any>;
  const list = ensureArray(payload.list ?? payload.data ?? []).map(mapCategory);
  const pagination = normalisePagination(
    payload.pagination ?? payload,
    page,
    pageSize,
    list.length
  );

  return {
    list,
    pagination: {
      total: pagination.total,
      pageSize: pagination.pageSize,
      currentPage: pagination.currentPage
    }
  };
};

const fetchTree = async (
  filters: Partial<CategoryListParams> = {}
): Promise<CategoryTreeNode[]> => {
  const res = await http.request<ApiResponse<any>>("get", CATEGORY_ENDPOINT, {
    params: {
      ...filters,
      as_tree: true
    }
  });

  return mapTree(res?.data ?? []);
};

const fetchAll = async (
  filters: Partial<CategoryListParams> = {}
): Promise<CategoryListItem[]> => {
  const res = await http.request<ApiResponse<any>>("get", CATEGORY_ENDPOINT, {
    params: {
      ...filters,
      page: 1,
      page_size: 500
    }
  });

  const payload = (res?.data ?? {}) as Record<string, any>;
  return ensureArray(payload.list ?? payload.data ?? []).map(mapCategory);
};

const getCategory = async (id: number | string): Promise<CategoryDetail> => {
  const res = await http.request<ApiResponse<Record<string, any>>>(
    "get",
    `${CATEGORY_ENDPOINT}/${id}`
  );
  return mapCategory(res?.data ?? {});
};

const createCategory = async (payload: CategorySubmitPayload) => {
  const data = mapSubmitPayload(payload);
  return http.request<ApiResponse<any>>("post", CATEGORY_ENDPOINT, {
    data
  });
};

const updateCategory = async (
  id: number | string,
  payload: CategorySubmitPayload
) => {
  const data = mapSubmitPayload(payload);
  return http.request<ApiResponse<any>>("put", `${CATEGORY_ENDPOINT}/${id}`, {
    data
  });
};

const removeCategory = async (id: number | string) => {
  return http.request<ApiResponse<any>>("delete", `${CATEGORY_ENDPOINT}/${id}`);
};

export default {
  fetchList,
  fetchTree,
  fetchAll,
  get: getCategory,
  create: createCategory,
  update: updateCategory,
  remove: removeCategory
};

export {
  fetchList,
  fetchTree,
  fetchAll,
  getCategory,
  createCategory,
  updateCategory,
  removeCategory
};
